Asinxron amallar yordamida ishga tushiriladigan holatni boshqarishni soddalashtirish uchun React'ning useActionState hook'ini o'rganing. Dasturingiz samaradorligi va foydalanuvchi tajribasini yaxshilang.
React useActionState qo‘llanilishi: Amallarga asoslangan holatni boshqarish
React'ning so'nggi versiyalarida taqdim etilgan useActionState hook'i asinxron amallar natijasida yuzaga keladigan holat yangilanishlarini boshqarishning takomillashtirilgan yondashuvini taklif etadi. Bu kuchli vosita, ayniqsa React Server Komponentlari (RSC) va server amallari bilan ishlaganda, mutatsiyalarni qayta ishlash, foydalanuvchi interfeysini (UI) yangilash va xatolik holatlarini boshqarish jarayonini soddalashtiradi. Ushbu qo'llanmada useActionStatening nozik jihatlari, amaliy misollar va uni qo'llash bo'yicha eng yaxshi amaliyotlar ko'rib chiqiladi.
Amallarga asoslangan holatni boshqarish zaruriyatini tushunish
An'anaviy React holatini boshqarish ko'pincha komponentlar ichida yuklanish va xatolik holatlarini alohida boshqarishni o'z ichiga oladi. Biror amal (masalan, formani yuborish, ma'lumotlarni olish) holat yangilanishini keltirib chiqarganda, dasturchilar odatda bu holatlarni bir nechta useState chaqiruvlari va murakkab shartli mantiq yordamida boshqaradilar. useActionState esa toza va integratsiyalashgan yechimni taqdim etadi.
Oddiy forma yuborish stsenariysini ko'rib chiqaylik. useActionStatesiz sizda quyidagilar bo'lishi mumkin:
- Forma ma'lumotlari uchun holat o'zgaruvchisi.
- Forma yuborilayotganini kuzatish uchun holat o'zgaruvchisi (yuklanish holati).
- Har qanday xato xabarlarini saqlash uchun holat o'zgaruvchisi.
Bu yondashuv kodning haddan tashqari ko'payishiga va nomuvofiqliklarga olib kelishi mumkin. useActionState bu muammolarni bitta hook'da birlashtirib, mantiqni soddalashtiradi va kodning o'qilishini yaxshilaydi.
useActionState bilan tanishuv
useActionState hook'i ikkita argument qabul qiladi:
- Holatni yangilaydigan asinxron funksiya ("amal"). Bu server amali yoki har qanday asinxron funksiya bo'lishi mumkin.
- Boshlang'ich holat qiymati.
U ikki elementdan iborat massiv qaytaradi:
- Joriy holat qiymati.
- Amalni jo'natish (dispatch) uchun funksiya. Bu funksiya amal bilan bog'liq yuklanish va xatolik holatlarini avtomatik ravishda boshqaradi.
Mana oddiy misol:
import { useActionState } from 'react';
async function updateServer(prevState, formData) {
// Simulate an asynchronous server update.
await new Promise(resolve => setTimeout(resolve, 1000));
const data = Object.fromEntries(formData);
if (data.name === "error") {
return 'Failed to update server.';
}
return `Updated name to: ${data.name}`;
}
function MyComponent() {
const [state, dispatch] = useActionState(updateServer, 'Initial State');
async function handleSubmit(event) {
event.preventDefault();
const formData = new FormData(event.target);
const result = await dispatch(formData);
console.log(result);
}
return (
);
}
Ushbu misolda:
updateServer- serverni yangilashni simulyatsiya qiluvchi asinxron amal. U avvalgi holatni va forma ma'lumotlarini qabul qiladi.useActionStateholatni 'Initial State' bilan ishga tushiradi va joriy holat hamdadispatchfunksiyasini qaytaradi.handleSubmitfunksiyasidispatchni forma ma'lumotlari bilan chaqiradi.useActionStateamal bajarilishi davomida yuklanish va xatolik holatlarini avtomatik ravishda boshqaradi.
Yuklanish va xatolik holatlarini boshqarish
useActionStatening asosiy afzalliklaridan biri bu yuklanish va xatolik holatlarini o'rnatilgan tarzda boshqarishidir. dispatch funksiyasi amal natijasi bilan yakunlanadigan promise qaytaradi. Agar amal xatolik yuzaga keltirsa, promise xato bilan rad etiladi. Siz buni UI'ni mos ravishda yangilash uchun ishlatishingiz mumkin.
Oldingi misolni yuklanish xabari va xato xabarini ko'rsatish uchun o'zgartiramiz:
import { useActionState } from 'react';
import { useState } from 'react';
async function updateServer(prevState, formData) {
// Simulate an asynchronous server update.
await new Promise(resolve => setTimeout(resolve, 1000));
const data = Object.fromEntries(formData);
if (data.name === "error") {
throw new Error('Failed to update server.');
}
return `Updated name to: ${data.name}`;
}
function MyComponent() {
const [state, dispatch] = useActionState(updateServer, 'Initial State');
const [isSubmitting, setIsSubmitting] = useState(false);
const [errorMessage, setErrorMessage] = useState(null);
async function handleSubmit(event) {
event.preventDefault();
const formData = new FormData(event.target);
setIsSubmitting(true);
setErrorMessage(null);
try {
const result = await dispatch(formData);
console.log(result);
} catch (error) {
console.error("Error during submission:", error);
setErrorMessage(error.message);
} finally {
setIsSubmitting(false);
}
}
return (
);
}
Asosiy o'zgarishlar:
- Yuklanish va xatolik holatlarini kuzatish uchun
isSubmittingvaerrorMessageholat o'zgaruvchilarini qo'shdik. handleSubmitichidadispatchni chaqirishdan oldinisSubmittingnitrueqilib belgilaymiz vaerrorMessageni yangilash uchun har qanday xatoliklarni ushlaymiz.- Yuborish paytida yuborish tugmasini o'chirib qo'yamiz va yuklanish hamda xatolik xabarlarini shartli ravishda ko'rsatamiz.
React Server Komponentlarida (RSC) server amallari bilan useActionState'dan foydalanish
useActionState React Server Komponentlari (RSC) va server amallari bilan ishlatilganda o'zining afzalliklarini namoyon qiladi. Server amallari serverda ishlaydigan va ma'lumotlar manbalarini to'g'ridan-to'g'ri o'zgartira oladigan funksiyalardir. Ular sizga API endpoint'larini yozmasdan server tomonidagi operatsiyalarni bajarish imkonini beradi.
Eslatma: Ushbu misol Server Komponentlari va Server Amallari uchun sozlangan React muhitini talab qiladi.
// app/actions.js (Server Action)
'use server';
import { cookies } from 'next/headers'; //Example, for Next.js
export async function updateName(prevState, formData) {
const name = formData.get('name');
if (!name) {
return 'Please enter a name.';
}
try {
// Simulate database update.
await new Promise(resolve => setTimeout(resolve, 1000));
cookies().set('userName', name);
return `Updated name to: ${name}`; //Success!
} catch (error) {
console.error("Database update failed:", error);
return 'Failed to update name.'; // Important: Return a message, not throw an Error
}
}
// app/page.jsx (React Server Component)
'use client';
import { useActionState } from 'react';
import { updateName } from './actions';
function MyComponent() {
const [state, dispatch] = useActionState(updateName, 'Initial State');
async function handleSubmit(event) {
event.preventDefault();
const formData = new FormData(event.target);
const result = await dispatch(formData);
console.log(result);
}
return (
);
}
export default MyComponent;
Ushbu misolda:
updateName- buapp/actions.jsfaylida aniqlangan server amali. U oldingi holat va forma ma'lumotlarini qabul qiladi, ma'lumotlar bazasini yangilaydi (simulyatsiya qilingan) va muvaffaqiyat yoki xato xabarini qaytaradi. Muhimi, amal xatolik qaytarish o'rniga xabar qaytaradi. Server Amallari ma'lumot beruvchi xabarlarni qaytarishni afzal ko'radi.- Komponent
useActionStatehook'idan foydalanish uchun mijoz komponenti ('use client') sifatida belgilangan. handleSubmitfunksiyasidispatchni forma ma'lumotlari bilan chaqiradi.useActionStateserver amali natijasiga qarab holat yangilanishini avtomatik ravishda boshqaradi.
Server Amallari uchun muhim mulohazalar
- Server Amallarida xatoliklarni qayta ishlash: Xatolik yuzaga keltirish o'rniga, Server Amalingizdan mazmunli xato xabarini qaytaring.
useActionStatebu xabarni yangi holat sifatida qabul qiladi. Bu mijoz tomonida xatoliklarni oson boshqarish imkonini beradi. - Optimistik yangilanishlar: Idrok etilgan ishlash samaradorligini oshirish uchun server amallarini optimistik yangilanishlar bilan ishlatish mumkin. Siz UI'ni darhol yangilab, agar amal muvaffaqiyatsiz bo'lsa, uni bekor qilishingiz mumkin.
- Qayta tasdiqlash (Revalidation): Muvaffaqiyatli mutatsiyadan so'ng, UI eng so'nggi holatni aks ettirishini ta'minlash uchun keshdagi ma'lumotlarni qayta tasdiqlashni ko'rib chiqing.
useActionState'ning ilg'or usullari
1. Murakkab holat yangilanishlari uchun Reducer'dan foydalanish
Murakkabroq holat mantig'i uchun siz useActionStateni reducer funksiyasi bilan birlashtirishingiz mumkin. Bu sizga holat yangilanishlarini bashorat qilinadigan va qo'llab-quvvatlanadigan tarzda boshqarish imkonini beradi.
import { useActionState } from 'react';
import { useReducer } from 'react';
const initialState = {
count: 0,
message: 'Initial State',
};
function reducer(state, action) {
switch (action.type) {
case 'INCREMENT':
return { ...state, count: state.count + 1 };
case 'DECREMENT':
return { ...state, count: state.count - 1 };
case 'SET_MESSAGE':
return { ...state, message: action.payload };
default:
return state;
}
}
async function updateState(state, action) {
// Simulate asynchronous operation.
await new Promise(resolve => setTimeout(resolve, 500));
switch (action.type) {
case 'INCREMENT':
return reducer(state, action);
case 'DECREMENT':
return reducer(state, action);
case 'SET_MESSAGE':
return reducer(state, action);
default:
return state;
}
}
function MyComponent() {
const [state, dispatch] = useActionState(updateState, initialState);
return (
Count: {state.count}
Message: {state.message}
);
}
2. useActionState bilan optimistik yangilanishlar
Optimistik yangilanishlar foydalanuvchi tajribasini yaxshilaydi, chunki UI amal muvaffaqiyatli bo'lgandek darhol yangilanadi va agar amal muvaffaqiyatsiz bo'lsa, yangilanish bekor qilinadi. Bu dasturingizni yanada sezgir his qildirishga yordam beradi.
import { useActionState } from 'react';
import { useState } from 'react';
async function updateServer(prevState, formData) {
// Simulate an asynchronous server update.
await new Promise(resolve => setTimeout(resolve, 1000));
const data = Object.fromEntries(formData);
if (data.name === "error") {
throw new Error('Failed to update server.');
}
return `Updated name to: ${data.name}`;
}
function MyComponent() {
const [name, setName] = useState('Initial Name');
const [state, dispatch] = useActionState(async (prevName, newName) => {
try {
const result = await updateServer(prevName, {
name: newName,
});
return newName; // Update on success
} catch (error) {
// Revert on error
console.error("Update failed:", error);
setName(prevName);
return prevName;
}
}, name);
async function handleSubmit(event) {
event.preventDefault();
const formData = new FormData(event.target);
const newName = formData.get('name');
setName(newName); // Optimistically update UI
await dispatch(newName);
}
return (
);
}
3. Amallarni kechiktirish (Debouncing)
Ba'zi stsenariylarda siz amallarni juda tez-tez jo'natilishining oldini olish uchun ularni kechiktirishni xohlashingiz mumkin. Bu, masalan, qidiruv maydonlari kabi holatlarda foydali bo'lishi mumkin, bunda siz faqat foydalanuvchi yozishni to'xtatgandan keyin ma'lum bir vaqt o'tgach amalni ishga tushirishni xohlaysiz.
import { useActionState } from 'react';
import { useState, useEffect } from 'react';
async function searchItems(prevState, query) {
// Simulate asynchronous search.
await new Promise(resolve => setTimeout(resolve, 500));
return `Search results for: ${query}`;
}
function MyComponent() {
const [query, setQuery] = useState('');
const [state, dispatch] = useActionState(searchItems, 'Initial State');
useEffect(() => {
const timeoutId = setTimeout(() => {
if (query) {
dispatch(query);
}
}, 300); // Debounce for 300ms
return () => clearTimeout(timeoutId);
}, [query, dispatch]);
return (
setQuery(e.target.value)}
/>
State: {state}
);
}
useActionState uchun eng yaxshi amaliyotlar
- Amallarni toza saqlang: Amallaringiz toza funksiyalar (yoki iloji boricha shunday) ekanligiga ishonch hosil qiling. Ular holatni yangilashdan boshqa yon ta'sirlarga ega bo'lmasligi kerak.
- Xatoliklarni ehtiyotkorlik bilan boshqaring: Amallaringizdagi xatoliklarni har doim boshqaring va foydalanuvchiga ma'lumot beruvchi xato xabarlarini taqdim eting. Server Amallari bilan yuqorida aytib o'tilganidek, xatolik yuzaga keltirish o'rniga, server amalidan xato xabari satrini qaytarishni afzal ko'ring.
- Ishlash samaradorligini optimallashtiring: Amallaringizning ishlash samaradorligiga ta'sirini, ayniqsa katta ma'lumotlar to'plamlari bilan ishlaganda, yodda tuting. Keraksiz qayta renderlardan qochish uchun memoizatsiya usullaridan foydalanishni ko'rib chiqing.
- Foydalanish imkoniyatlarini (Accessibility) hisobga oling: Dasturingiz barcha foydalanuvchilar, shu jumladan nogironligi bo'lganlar uchun ham qulay bo'lishini ta'minlang. Tegishli ARIA atributlari va klaviatura navigatsiyasini ta'minlang.
- Puxta sinovdan o'tkazish: Amallaringiz va holat yangilanishlaringiz to'g'ri ishlayotganiga ishonch hosil qilish uchun birlik testlari va integratsiya testlarini yozing.
- Xalqarolashtirish (i18n): Global dasturlar uchun bir nechta til va madaniyatlarni qo'llab-quvvatlash uchun i18n'ni amalga oshiring.
- Mahalliylashtirish (l10n): Mahalliy tarkib, sana formatlari va valyuta belgilarini taqdim etish orqali dasturingizni ma'lum bir hududga moslashtiring.
useActionState va boshqa holatni boshqarish yechimlari
useActionState amallarga asoslangan holat yangilanishlarini boshqarishning qulay usulini taqdim etsa-da, u barcha holatni boshqarish yechimlarining o'rnini bosa olmaydi. Bir nechta komponentlar o'rtasida bo'lishilishi kerak bo'lgan global holatga ega murakkab dasturlar uchun Redux, Zustand yoki Jotai kabi kutubxonalar mosroq bo'lishi mumkin.
useActionState qachon ishlatiladi:
- Oddiy va o'rtacha murakkablikdagi holat yangilanishlari.
- Asinxron amallar bilan chambarchas bog'liq bo'lgan holat yangilanishlari.
- React Server Komponentlari va Server Amallari bilan integratsiya.
Boshqa yechimlarni qachon ko'rib chiqish kerak:
- Murakkab global holatni boshqarish.
- Ko'p sonli komponentlar o'rtasida bo'lishilishi kerak bo'lgan holat.
- Vaqt bo'ylab sayohat (time-travel debugging) yoki oraliq dasturiy ta'minot (middleware) kabi ilg'or xususiyatlar.
Xulosa
React'ning useActionState hook'i asinxron amallar tomonidan ishga tushiriladigan holat yangilanishlarini boshqarishning kuchli va oqilona usulini taklif etadi. Yuklanish va xatolik holatlarini birlashtirish orqali u kodni soddalashtiradi va o'qilishini yaxshilaydi, ayniqsa React Server Komponentlari va server amallari bilan ishlaganda. Uning kuchli va zaif tomonlarini tushunish dasturingiz uchun to'g'ri holatni boshqarish yondashuvini tanlash imkonini beradi, bu esa yanada qo'llab-quvvatlanadigan va samarali kodga olib keladi.
Ushbu qo'llanmada keltirilgan eng yaxshi amaliyotlarga rioya qilish orqali siz useActionStatedan dasturingizning foydalanuvchi tajribasi va ishlab chiqish jarayonini yaxshilash uchun samarali foydalanishingiz mumkin. Dasturingizning murakkabligini hisobga olishni va ehtiyojlaringizga eng mos keladigan holatni boshqarish yechimini tanlashni unutmang. Oddiy forma yuborishlardan tortib murakkab ma'lumotlar mutatsiyalarigacha, useActionState sizning React ishlab chiqish arsenalingizda qimmatli vosita bo'lishi mumkin.